﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ElectronicJournal.Account.AuthorAccount;

namespace ElectronicJournal
{
    //  public delegate void NewAuthorAddedDelegate(Author author);

    public class EJournalRepository
    {
        //  public event NewAuthorAddedDelegate NewAuthorAddedDelegateEvent;

        //public void InvokeNewAuthorAddedDelegateEvent()
        //{
        //    NewAuthorAddedDelegate handler = NewAuthorAddedDelegateEvent;
        //    if (handler != null) handler(this);
        //}
        private const string SOMEE_CONN_STRING = @"workstation id=EJournalDB.mssql.somee.com;packet size=4096;user id=varela_SQLLogin_1;pwd=t3m3exaq6p;data source=EJournalDB.mssql.somee.com;persist security info=False;initial catalog=EJournalDB";
        private EJournalDBClassesDataContext _eJDataContext;
        protected EJournalRepository()
        {
            _eJDataContext = new EJournalDBClassesDataContext(SOMEE_CONN_STRING);
        }

        private sealed class RepositoryCreator
        {
            private static readonly EJournalRepository instance = new EJournalRepository();
            public static EJournalRepository Instance { get { return instance; } }
        }

        public static EJournalRepository Instance
        {
            get { return RepositoryCreator.Instance; }
        }

        public Guid AddAuthor(String authorName,
            string authorSurname,
            string thirdName,
            string authorEmail,
            bool receivesPubState,
            bool receivesNews,
            string authorPhoneNumber,
            Guid authorUserId,
            Guid scientificDir
            )
        {
            var newAuthor = new Author();
            newAuthor.AuthorFirstName = authorName;
            newAuthor.AuthorSecondName = authorSurname;
            newAuthor.AuthorThirdName = thirdName;
            newAuthor.AuthorUserId = authorUserId;
            newAuthor.AuthorEmail = authorEmail;
            newAuthor.AuthorReceivesMagazineNews = receivesNews;
            newAuthor.AuthorReceivesPublicationState = receivesPubState;
            newAuthor.AuthorPhoneNumber = authorPhoneNumber;
            newAuthor.AuthorScientificDirectionId = scientificDir;
            newAuthor.AuthorId = Guid.NewGuid();

            _eJDataContext.Authors.InsertOnSubmit(newAuthor);
            _eJDataContext.SubmitChanges();

            return newAuthor.AuthorId;
        }

        public void AddReviewer(String name,
          string surname,
          string thirdName,
          string email,
          string number,
          Boolean receivesByEmail,
          Boolean receivesBySms,
          Guid UserId)
        {
            var reviewer = new Reviewer()
            {
                ReviewerUserId = UserId,
                ReviewerEmail = email,
                ReviewerFirstName = name,
                ReviewerLastName = surname,
                ReviewerThirdName = thirdName,
                ReviewerReceivesByMail = receivesByEmail,
                ReviewersReceivesBySms = receivesBySms,
                ReviewerPhoneNumber = number
            };

            _eJDataContext.Reviewers.InsertOnSubmit(reviewer);
            _eJDataContext.SubmitChanges();
        }

        public List<ScientificDirection> AllScientificFirection()
        {
            return _eJDataContext.ScientificDirections.ToList();
        }

        public bool IsSubmitRegistration(Guid userGuid) // проверка подтверждения регистрации
        {
            if (_eJDataContext.Authors.ToList().Where(n => n.AuthorUserId == userGuid).Count() != 0 ||
                _eJDataContext.Reviewers.ToList().Where(n => n.ReviewerUserId == userGuid).Count() != 0)
            {
                return true;
            }
            return false;
        }

        public List<Publication> GetAllPublicationsForAuthor(Guid userId)
        {
            Guid authorId = _eJDataContext.Authors.Single(n => n.AuthorUserId == userId).AuthorId;
            List<Publication> PubList = new List<Publication>();
            _eJDataContext.AuthorToPubs.ToList().ForEach(autToPub =>
                                                             {
                                                                 if (autToPub.AuthorId == authorId)
                                                                     PubList.Add(
                                                                         _eJDataContext.Publications.Single(
                                                                             pub => pub.Id == autToPub.PubId));
                                                             });
            return PubList;
        }

        public void AddPublication(Guid authorUserGuid, string titleRussian, string titleEnglish, Guid scientificDirection, Guid publicationType, 
            int udcId, string summaryRussian, string summaryEnglish, string keywordsRussian, string keywordsEnglish, string speciality, 
            string fileArticle, string fileExpert, string fileLetter, DateTime date, int state, 
            IEnumerable<Coauthor> coauthors)
        {
            Publication newPublication = new Publication() 
            {
                TitleRussian = titleRussian,
                TitleEnglish = titleEnglish,
                ScientificDirection = scientificDirection,
                Type = publicationType,
                UDCIndex = udcId,
                SummaryRussian = summaryRussian,
                SummaryEnglish = summaryEnglish,
                KeywordsEnglish = keywordsEnglish,
                KeywordsRussian = keywordsRussian,
                Speciality = speciality, //
                FileArticle = fileArticle,
                FileExpert = fileExpert,
                FileLetter = fileLetter,
                Date = date,
                State = state //
            };

            _eJDataContext.Publications.InsertOnSubmit(newPublication);
            _eJDataContext.SubmitChanges();

            var currentAuthor = GetAuthorByUserId(authorUserGuid);
            AddAuthorToPublication(currentAuthor.AuthorId, newPublication.Id);
            AddCoauthorsToPulication(newPublication.Id, currentAuthor, coauthors);
        }


        protected void AddCoauthorsToPulication(Guid publicationId, Author currentAuthor, IEnumerable<Coauthor> coauthors)
        {
            try
            {
                if (coauthors != null)
                {
                    if (coauthors.Count() > 0)
                    {
                        var resultCoauthorsList = new List<Coauthor>(coauthors);
                        var coauthorsUserId = _eJDataContext.aspnet_Users.Single(user => user.UserName.Equals("coauthor")).UserId;

                        //Всех соавторов добавить в таблицу с авторами
                        resultCoauthorsList.ForEach(coauthor =>
                        {

                            //Добавить соавтора в таблицу Авторы
                            Guid authorId = AddAuthor(coauthor.firstName, coauthor.lastName, coauthor.thirdName,
                               coauthor.email, false, false, coauthor.phoneNumber, coauthorsUserId, currentAuthor.AuthorScientificDirectionId);

                            //Связать соавтора с публикацией автора
                            AddAuthorToPublication(authorId, publicationId);
                        });
                    }
                }
            }
            catch (NullReferenceException nrEx)
            {
            }
        }

        public void AddAuthorToPublication(Guid authorGuid, Guid publicationGuid)
        {
            AuthorToPub authorToPub = new AuthorToPub()
            {
                AuthorId = authorGuid,
                PubId = publicationGuid,
            };
            _eJDataContext.AuthorToPubs.InsertOnSubmit(authorToPub);
            _eJDataContext.SubmitChanges();
        }

        public IEnumerable<Review> GetAllAuthorsReviews(Guid PublicationId)
        {
            return _eJDataContext.Reviews.Where(rev => rev.ReviewArticleId.Equals(PublicationId)).AsEnumerable();
        }

        public IEnumerable<ScientificDirection> GetAllScientificDirections()
        {
            return _eJDataContext.ScientificDirections.AsEnumerable().Cast<ScientificDirection>();
        }

        public ScientificDirection GetScientificDirectionById(Guid scientificDirectionGuid)
        {
            var ScientificDirections = GetAllScientificDirections();
            return ScientificDirections.Single(scientificDirection => scientificDirection.Id == scientificDirectionGuid);
        }

        public IEnumerable<PublicationType> GetAllPublicationTypes()
        {
            return _eJDataContext.PublicationTypes.AsEnumerable().Cast<PublicationType>();
        }

        public IEnumerable<UDC> GetAllUDCs()
        {
            return _eJDataContext.UDCs.AsEnumerable().Cast<UDC>();
        }

        public Author GetAuthorByUserId(Guid userId)
        {
            return _eJDataContext.Authors.Single(author => author.AuthorUserId.Equals(userId));
        }


        public Reviewer GetReviewerByUserId(Guid userId)
        {
            return _eJDataContext.Reviewers.Single(author => author.ReviewerUserId.Equals(userId));
        }

        public List<Publication> GetAllPubForReviewer(int reviewerId)
        {
            var reviews = _eJDataContext.Reviews.Where(rev => rev.ReviewReiewerId.Equals(reviewerId));
            List<Publication> pubs = new List<Publication>();
            List<Publication> allPubs = _eJDataContext.Publications.ToList<Publication>();
            reviews.ToList().ForEach(rev => { if (!pubs.Contains(allPubs.Single(pub => pub.Id.Equals(rev.Publication.Id))))  pubs.Add(allPubs.Single(pub => pub.Id.Equals(rev.Publication.Id))); });
            
            return pubs;
        }



        public OrganizationInformation GetOrganizationInformation()
        {
            return _eJDataContext.OrganizationInformations.First();
        }

        public State GetStateByArticleId(Guid articleId)
        {
            var article = _eJDataContext.Publications.Single(pub=>pub.Id.Equals(articleId));

            return _eJDataContext.States.Single(state=>state.StateId.Equals(article.State));
        }
       //// необходимо добавить ID Journal
       // public Journal  GetJournalByPub(Publication publication)
       // {
       //     return _eJDataContext.Journals.Where(j => j.JournalId == publication.); 
       // }

        public void RefreshReview(string link, DateTime date, Guid pubId)
        {

                //_eJDataContext.Reviews.Single(rev => rev.ReviewId == review.ReviewId).ReviewContentLink =
                //    review.ReviewContentLink;
                //_eJDataContext.Reviews.Single(rev => rev.ReviewId == review.ReviewId).ReviewDate =
                //    review.ReviewDate;

            
           // GetPublicationById(Guid.Parse(review.ReviewArticleId.ToString())).State = 2;


            Review lastReview = GetAllReviewForPublication(pubId).Last();
            lastReview.ReviewContentLink = link;
            lastReview.ReviewDate = date;
            _eJDataContext.SubmitChanges();
        }
        public bool IsReviewThisArticle(Publication publication)// статье нужна рецензия
        {
            if (publication.State == 2)
                return true;
            return false;

        }

        public void RefreshArticleState(int stateAfter, Guid pubId)
        {
            GetPublicationById(pubId).State = stateAfter;
        }

        public void RefreshStateAfterReview(int state, Guid publicationId, string notes)
        {
            Publication publication = _eJDataContext.Publications.Single(pub => pub.Id == publicationId);

            publication.State = 3;
            publication.PublicationNotes = notes;
            _eJDataContext.SubmitChanges();

        }

        public Publication GetPublicationById(Guid idPub)
        {
            return _eJDataContext.Publications.Single(pub => pub.Id == idPub);
        }

        public List<Review> GetAllReviewForPublication (Guid pubId)
        {
            return  _eJDataContext.Reviews.Where(rev => rev.ReviewArticleId == pubId).ToList();
        }

        public List<Pattern> GetAllPattern()
        {
            return _eJDataContext.Patterns.ToList();
        }


        public void SaveRecieptNumberPublications(Guid pubId, string number)
        {
            _eJDataContext.Publications.Single(n => n.Id == pubId).PubicationReceiptNumber = number;
            _eJDataContext.SubmitChanges();
        }

        //public Journal GetJournalByPub(Guid pubId)
        //{
        //    Guid journalId = _eJDataContext.PublicationsInJournals.Single(journal => journal.PublicationId == pubId).JournalId;
        //    return _eJDataContext.Journals.Single(journal => journal.JournalId == journalId);
        //}
    }
}